package com.disc.baidu;

import com.alibaba.fastjson.JSONObject;
import com.disc.common.Constant;
import com.disc.common.DiscResponse;
import com.disc.util.BaseUtil;
import com.disc.util.HttpUtil;
import com.disc.util.RSAUtils;
import com.disc.util.RegexUtil;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * Created by Tonight on 2017/7/18.
 */
public class BaiDuLogin {

     public CookieStore cookieStore =  new BasicCookieStore();

     public CloseableHttpClient httpclient;

     public String budss;

     public String token;

     public String baiduId;

     public String type = "TIANYI";

     public Date createTime;

     String codeString;
    /**
     * 初始化cookie
     */
    public void initCookie()
    {
        HttpUtil.createHttpGet(Constant.BAIDU_GET_COOKIE,httpclient);
    }

    /**
     * 初始化httpclient
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public BaiDuLogin()  throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException
    {
        httpclient =  HttpClients.custom().useSystemProperties().setConnectionManager(HttpUtil.getSSLNoCheckConnectionManager()).setDefaultCookieStore(cookieStore).build();
    }

    /**
     * 初始化cookie
     */
    public  String getToken()
    {
        String url = String.format(Constant.BAIDU_GET_TOKEN, BaseUtil.getBaiDuTimes(),"%s");
        String result =  HttpUtil.createHttpGet(url,httpclient);
        JSONObject jsonObject = JSONObject.parseObject(result);
        token =jsonObject.getJSONObject("data").getString("token");
        return token;
    }


    public  Map<String,String> getPublicKey(String token)
    {
        String url = String.format(Constant.BAIDU_GET_PUBLIC_KEY,token,"%s");
        String result =  HttpUtil.createHttpGet(url,httpclient);
        JSONObject jsonObject = JSONObject.parseObject(result);
        Map<String,String> resultMap = new HashMap<String, String>();
        resultMap.put("pubkey",jsonObject.getString("pubkey"));
        resultMap.put("key",jsonObject.getString("key"));
        return resultMap;
    }

    public DiscResponse login(Map<String,String> resultPublicKeyMap,String  token,BaiduUser baiduUser) throws Exception {
        String passwordEncrypted = RSAUtils.encryptToBase64StringByPublicKey(RSAUtils.readPublicKey(resultPublicKeyMap.get("pubkey")),baiduUser.getPassword());
            List <NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("staticpage","http://www.baidu.com/cache/user/html/v3Jump.html"));
            nvps.add(new BasicNameValuePair("charset", "UTF-8"));
            nvps.add(new BasicNameValuePair("token",token));
            nvps.add(new BasicNameValuePair("tpl", "pp"));
            nvps.add(new BasicNameValuePair("subpro", ""));
            nvps.add(new BasicNameValuePair("apiver", "v3"));
            nvps.add(new BasicNameValuePair("tt", String.valueOf(System.currentTimeMillis()).substring(0,10)));
            nvps.add(new BasicNameValuePair("codestring", codeString));
            nvps.add(new BasicNameValuePair("isPhone", "false"));
            nvps.add(new BasicNameValuePair("safeflg", "0"));
            nvps.add(new BasicNameValuePair("u", "https://passport.baidu.com/"));
            nvps.add(new BasicNameValuePair("quick_user", "0"));
            nvps.add(new BasicNameValuePair("logLoginType", "pc_loginBasic"));
            nvps.add(new BasicNameValuePair("loginmerge", "true"));
            nvps.add(new BasicNameValuePair("logintype", "basicLogin"));
            nvps.add(new BasicNameValuePair("username", baiduUser.getAccount()));
            nvps.add(new BasicNameValuePair("password", passwordEncrypted));
            nvps.add(new BasicNameValuePair("verifycode", baiduUser.getVerificationCode()));
            nvps.add(new BasicNameValuePair("mem_pass", "on"));
            nvps.add(new BasicNameValuePair("rsakey", resultPublicKeyMap.get("key")));
            nvps.add(new BasicNameValuePair("crypttype", "12"));
            nvps.add(new BasicNameValuePair("ppui_logintime", "50918"));
            nvps.add(new BasicNameValuePair("callback", "parent.bd__pcbs__oa36qm"));
            String content =   HttpUtil.createHttpPost(Constant.BAIDU_LOGIN,nvps,httpclient);
            DiscResponse discResponse = checkAccountException(content);
            if(content.contains("err_no=257") || content.contains("err_no=6"))
            {
                codeString = RegexUtil.findAll(content,"codeString=(.*?)&",1).get(0);

                String urlVerifyCode = String.format(Constant.BAIDU_VERIFICATION_CODE,codeString,"%s");

                Map<String,String> map = new HashMap<>();

                map.put("url",urlVerifyCode);

                discResponse.setResult(map);
            }

            return discResponse;
    }

    /**
     * 检测登陆响应
     * @param content
     * @return
     */
    protected DiscResponse checkAccountException(String content)
    {
        DiscResponse discResponse = new DiscResponse();
        String errorId = RegexUtil.findAll(content, "err_no=([\\d]+)",1).get(0);
        discResponse.setCode(errorId);
        if(errorId.equals("0"))
        {
            List<Cookie> list =  cookieStore.getCookies();
            for (Cookie item :list)
            {
                if("BDUSS".equals(item.getName()))
                {
                    budss = item.getValue();
                }
                if("BAIDUID".equals(item.getName()))
                {
                    baiduId = item.getValue();
                }
                System.out.println("登陆成功 cookie 值：" + item.getName()  + "----" + item.getValue() );
            }
            return discResponse;
        }
        String msg;
        if(Constant.errorMessageMap.containsKey(errorId))
        {
            msg = Constant.errorMessageMap.get(errorId);
        }
        else
        {
            msg = "unknown err_id=" + errorId;
        }
        discResponse.setMessage(msg);
        return discResponse;
    }
}
